#ifndef _INC_CONTAINER_T_H_
#define _INC_CONTAINER_T_H_

#include "Iterator_t.h"

template<class T>
class Container_t
{
public:
	/**
	* Ctor
	*/
	Container_t();

	/**
	* Dtor
	*/
	virtual ~Container_t();

	/**
	* Copy Ctor
	*/
	Container_t(const Container_t& other);

	/**
	* Assignment operator
	*/
	Container_t& operator=(const Container_t& other);

	/**
	* Returns amount of elements in container
	*/
	size_t count() const;

	/**
	* Returns pointer to elem with given value, returns NULL if not found
	*/
	T* find(const T& value);

	/**
	* Inserts elem at end of container
	*/
	void insert(T* const elem);

	/**
	* Inserts elem after given index in container
	* Throws exception in case index is out of bounds
	*/
	void append(T* const elem, int index);

	/**
	* Inserts elem before given index in container
	* Throws exception in case index is out of bounds
	*/
	void prepend(T* const elem, int index);

	/**
	* Attempts to remove elem with given value from container
	* Returns pointer to elem if successful, NULL otherwise
	*/
	T* remove(const T& value);

	/**
	* Attempts to remove and delete elem with given value from container
	* Returns true if successful, false otherwise
	*/
	bool removeAndDelete(const T& value);

	/**
	* Removes all elements from container
	*/
	void removeAll();

	/**
	* Removes and deletes all elements from container
	*/
	void removeAndDeleteAll();

	/** 
	* Helper function: prints all the elements of the container
	*/
	void print() const;

protected:
	/**
	* Returns next element in container
	*/
	virtual T* next() = 0;

	/**
	* Returns previous element in container
	*/
	virtual T* prev() = 0;

	/**
	* Resets inner container iterator
	*/
	virtual void reset() = 0;

	/**
	* Inserts elem after given index in container
	* Precondition: -1 <= index <= count() - 1
	*/
	virtual void doAppend(T* const elem, int index) = 0;

	/**
	* Removes elem with given value from container
	*/
	virtual void doRemove(const T& value) = 0;

	/**
	* Removes all elements from container
	*/
	virtual void doRemoveAll() = 0;

	/**
	* Removes and deletes all elements from container
	*/
	virtual void doRemoveAndDeleteAll() = 0;

	/**
	* Returns container iterator
	* Releasing iterator is up to caller
	*/
	virtual Iterator_t<T>* iterator() const = 0;

private:
	size_t m_count;
};

#include "Container_t.hpp"

#endif // _INC_CONTAINER_T_H_